import axios, { HttpStatusCode } from 'axios';
import { useGlobalStore } from '@/store/modules/global';
import { useUserStore } from '@/store/modules/user';
import router from "@/router";

import { AxiosCanceler } from './helper/axiosCancel';
import { checkStatus } from './helper/checkStatus';
import { resultStateMap } from './helper/httpState';
import { ElMessage } from 'element-plus';
import { showFullScreenLoading, tryHideFullScreenLoading } from './helper/serviceLoading';
import * as cookies from "@/utils/cache/cookies";

const axiosCanceler = new AxiosCanceler();

const { APP_BASE_URL } = window.config;

const config = {
    // 默认请求地址
    baseURL: APP_BASE_URL,
    // 设置超时时间
    timeout: 20000,
    // 跨域时允许携带凭证
    // withCredentials: false
};

class RequestHttp {
    constructor (config) {
        // 实例化axios
        this.service = axios.create(config);
        
       /**
       * @description 请求拦截器
       * 客户端发送请求 -> 请求拦截器 -> 服务器
       * token校验(JWT): 接受服务区返回的token，存储到pinia/本地存储当中
       */
        this.service.interceptors.request.use((config) => {
            // 将当前请求添加到 pending 中
            axiosCanceler.addPending(config);
            // const globalStore = useGlobalStore();
            const userStore = useUserStore();
            // 当前请求是否显示loading
            config.headers?.showLoading && showFullScreenLoading();
            
            const token = cookies.getToken();
            if(token){
                return { ...config, headers: { ...config.headers, 'token': `${token}`}};
            }
            // else{
            //     userStore.logout();
            // }
            
            return config;
        }, (error) => {
            return Promise.reject(error);
        });
        
        this.service.interceptors.response.use((response) => {
            const { data, config, headers } = response;
            const globalStore = useGlobalStore();
            const userStore = useUserStore();
            
            // 登陆失效处理
            if(headers?.sessiontimeout === 'sessionTimeOut'){
                userStore.logout().then(router.push('/login'))
            }
            
            // 请求结束后，移除本次请求，并关闭请求 loading
            axiosCanceler.removePending(config);
            tryHideFullScreenLoading();
            
            // 成功请求
            return data;
        }, async (error) => {
            const { response } = error;
            tryHideFullScreenLoading();
            
            // 请求超时单独判断，因为请求超时没有 response
            if(error.message.indexOf("timeout") !== -1) ElMessage.error("请求超时！请您稍后重试");
            
            // 根据相应的状态码，做不同的处理
            if(response) checkStatus(response.status);
            
            // 服务器结果都没有返回(可能服务器错误可能客户端断网), 断网处理：可以跳转到断网页面
            if(!window.navigator.onLine) router.replace({ path: '/500'});
            return Promise.reject(error);
        })
    }
    // 常用请求方法封装
    get (url, params, _object={}) {
        return this.service.get(url, { params, ..._object})
    }
    
    post (url, params, _object={}) {
        return this.service.post(url, params, _object);
    }
    
    put (url, params, _object={}) {
        return this.service.post(url, params, _object);
    }
    
    delete (url, params, _object={}) {
        return this.service.post(url, params, ..._object);
    }
}

export default new RequestHttp(config);